package com.sbtr.impl;


import com.sbtr.business.calibration.service.ICalibrationDetailsService;
import com.sbtr.business.calibration.service.ICalibrationFileService;
import com.sbtr.business.calibration.service.ICalibrationService;
import com.sbtr.business.calibration.service.ICalibrationTxtEntityService;
import com.sbtr.constant.CalibrationConstant;
import com.sbtr.open.calibration.dto.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 标注文本处理service
 *
 * @author zengjw5
 */
@Service
public class CalibrationTxtCommon {

    private static final Logger logger = LoggerFactory.getLogger(CalibrationTxtCommon.class);

    @Value("${oss.config.uploadPath}")
    private String uploadPath;

    @Autowired
    private ICalibrationTxtEntityService calibrationTxtEntityService;

    @Autowired
    private ICalibrationFileService calibrationFileService;

    @Autowired
    private ICalibrationDetailsService calibrationDetailsService;

    @Autowired
    private ICalibrationService calibrationService;

    public void divideTxt(CalibrationDto calibrationDto, CalibrationFileDto calibrationFileDto, MultipartFile multipartFiles, String finisher) {
        BufferedReader reader = null;
        List<CalibrationTxtEntityDto> calibrationTxtList = new ArrayList<>(); //以分隔符分割的素材
        try {
            //保存上传素材信息,返回id
            Long uploadTxtId = calibrationFileDto.getId();
            String creater = calibrationDto.getCreater();
            String encode = getEncode(multipartFiles);
            if ("".equals(encode)) {
                logger.error(multipartFiles.getName() + " 转换失败；");
            }
            reader = new BufferedReader(new InputStreamReader(multipartFiles.getInputStream(), encode));
            String line = "";

            while (StringUtils.isNotBlank(line = reader.readLine())) {
                calibrationTxtList.add(generate(line, calibrationDto.getId(), uploadTxtId, creater));

            }

            //设置每个人的条数
            String finishers[] = finisher.split(",");
            int userlength = finishers.length;
            for (int i = 0; i < calibrationTxtList.size(); i++) {
                int j = i % userlength;
                calibrationTxtList.get(i).setFinisher(finishers[j]);
            }


            //保存分割后的素材
            if (!calibrationTxtList.isEmpty()) {
                calibrationTxtEntityService.batchSave(calibrationTxtList);
            }
//            //修改关联素材信息

            List<CalibrationCountByFinisherDto> countTxtDto = calibrationTxtEntityService.countTaskByCalibrationIds(calibrationDto.getId());
            //查询明细表的每个人的任务
            List<CalibrationDetailsDto> calibrationDetailsDto = calibrationDetailsService.searchDetailsCalibrationId(calibrationDto.getId());
//			//查询总概览的任务
//			CalibrationDto calibrationDtos=calibrationService.findById(calibrationDto.getId());


            Set<String> allPeople = new HashSet<String>();
            Set<String> oldPeople = new HashSet<String>();
            Set<String> newPeople = new HashSet<String>();

            for (int i = 0; i < countTxtDto.size(); i++) {
                allPeople.add(countTxtDto.get(i).getFinisher());
            }
            for (int i = 0; i < calibrationDetailsDto.size(); i++) {
                oldPeople.add(calibrationDetailsDto.get(i).getFinisher());
            }


            for (String a : allPeople) {
                if (!oldPeople.contains(a)) {
                    newPeople.add(a);
                }
            }

            //更新每个人的数据
            int totalCount = 0;
            int completed = 0;


            if (calibrationDetailsDto.size() == 0) {//第一次导入数据

                List<CalibrationDetailsDto> newcalibrationDetails = new ArrayList<>();

                for (int i = 0; i < finishers.length; i++) {
                    totalCount += countTxtDto.get(i).getCompleted() + countTxtDto.get(i).getUncompleted();
                    completed += countTxtDto.get(i).getCompleted();

                    CalibrationDetailsDto calibrationDetail = new CalibrationDetailsDto();
                    calibrationDetail.setCalibrationDesc(calibrationDto.getCalibrationDesc());
                    calibrationDetail.setCalibrationId(calibrationDto.getId());
                    calibrationDetail.setCalibrationName(calibrationDto.getCalibrationName());
                    calibrationDetail.setPriority(calibrationDto.getPriority());
                    calibrationDetail.setCreater(calibrationDto.getCreater());
                    calibrationDetail.setFinishedTime(calibrationDto.getFinishedTime());
                    calibrationDetail.setFinisher(countTxtDto.get(i).getFinisher());
                    calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                    calibrationDetail.setCompleted(0);
                    calibrationDetail.setTaskType(calibrationDto.getTaskType());
                    calibrationDetail.setCreateTime(new Date());
                    calibrationDetail.setClassifyCount(0);
                    calibrationDetail.setTotalCount(countTxtDto.get(i).getCompleted() + countTxtDto.get(i).getUncompleted());
                    newcalibrationDetails.add(calibrationDetail);
                }
                calibrationDetailsService.batchSave(newcalibrationDetails);
            } else {//添加数据的情况


                List<CalibrationDetailsDto> calibrationDetails = new ArrayList<>(); //
                Integer classifyCount = calibrationDetailsDto.get(0).getClassifyCount();

                for (int i = 0; i < countTxtDto.size(); i++) {//所有人的
                    totalCount += countTxtDto.get(i).getCompleted() + countTxtDto.get(i).getUncompleted();
                    completed += countTxtDto.get(i).getCompleted();

                    if (newPeople.contains(countTxtDto.get(i).getFinisher())) {//新分配的人

                        CalibrationDetailsDto calibrationDetail = new CalibrationDetailsDto();
                        calibrationDetail.setCalibrationDesc(calibrationDto.getCalibrationDesc());
                        calibrationDetail.setCalibrationId(calibrationDto.getId());
                        calibrationDetail.setCalibrationName(calibrationDto.getCalibrationName());
                        calibrationDetail.setPriority(calibrationDto.getPriority());
                        calibrationDetail.setCreater(calibrationDto.getCreater());
                        calibrationDetail.setFinishedTime(calibrationDto.getFinishedTime());
                        calibrationDetail.setFinisher(countTxtDto.get(i).getFinisher());
                        calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                        calibrationDetail.setCompleted(0);
                        calibrationDetail.setTaskType(calibrationDto.getTaskType());
                        calibrationDetail.setCreateTime(new Date());
                        calibrationDetail.setClassifyCount(classifyCount);
                        calibrationDetail.setTotalCount(countTxtDto.get(i).getCompleted() + countTxtDto.get(i).getUncompleted());
                        calibrationDetails.add(calibrationDetail);

                    } else {//不是新人
                        for (CalibrationDetailsDto detailsDto : calibrationDetailsDto) {
                            if (detailsDto.getFinisher().equals(countTxtDto.get(i).getFinisher())) {
                                if (countTxtDto.get(i).getUncompleted() == 0) {//如果全部完成
                                    detailsDto.setStatus(CalibrationConstant.TASK_STATUS_COMPLETED);
                                    detailsDto.setCompleted(countTxtDto.get(i).getCompleted());
                                    detailsDto.setTotalCount(countTxtDto.get(i).getCompleted() + countTxtDto.get(i).getUncompleted());
                                } else {
                                    detailsDto.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                                    detailsDto.setCompleted(countTxtDto.get(i).getCompleted());
                                    detailsDto.setTotalCount(countTxtDto.get(i).getCompleted() + countTxtDto.get(i).getUncompleted());
                                }
                                calibrationDetailsService.update(detailsDto);
                            }
                        }

                    }
                }
                calibrationDetailsService.batchSave(calibrationDetails);
            }


            //更新总览的数据
            calibrationDto.setTotalCount(totalCount);
            calibrationDto.setCompleted(completed);

            if (totalCount != completed) calibrationDto.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
            calibrationService.update(calibrationDto);


            if (reader != null) {
                reader.close();
            }
        } catch (Exception e) {
            logger.error("文本分割异常 {}", e.toString());
        }
    }

    public CalibrationFileDto saveTxtInfo(MultipartFile file, CalibrationDto calibrationDto
    ) {

        String fileName = file.getOriginalFilename();
        String otherName = UUID.randomUUID().toString().replaceAll("-", "")
                + fileName.substring(fileName.lastIndexOf("."));

        String fileType = calibrationDto.getTaskType();
        String creater = calibrationDto.getCreater();

        String bucketDir = uploadPath + "/" + "calibration" + "/" + fileType + "/" + creater;

        OutputStream os = null;
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件
            File tempFile = new File(bucketDir);
            boolean results = tempFile.mkdirs();
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            os = new FileOutputStream(tempFile.getPath() + File.separator + otherName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        CalibrationFileDto calibrationFiles = new CalibrationFileDto();
        if (calibrationDto.getId() != null) {
            CalibrationFileDto calibrationFile = new CalibrationFileDto();
            calibrationFile.setBucketDir(bucketDir);
            calibrationFile.setCalibrationId(calibrationDto.getId());
            calibrationFile.setFileName(fileName);
            calibrationFile.setFileName2(otherName);

            calibrationFiles = calibrationFileService.save(calibrationFile);

        } else {
            return null;
        }


        return calibrationFiles;


    }

    private CalibrationTxtEntityDto generate(String content, Long id, Long uploadTxtId, String creater) {
        CalibrationTxtEntityDto dto = new CalibrationTxtEntityDto();
        dto.setTxtContent(content);
        dto.setCalibrationId(id);
        dto.setCreater(creater);
        dto.setCompleted("0");
        dto.setCalibrationFileId(uploadTxtId);
        return dto;
    }

    private String getEncode(MultipartFile multipartFile) {

        String str = "";
        String encode = "UTF-8";
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(multipartFile.getInputStream(), encode));
            str = br.readLine() + br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (!isMessyCode(str)) {
            return encode;
        }

        encode = "GB2312";
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(multipartFile.getInputStream(), encode));
            str = br.readLine() + br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (!isMessyCode(str)) {
            return encode;
        }

        encode = "GBK";
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(multipartFile.getInputStream(), encode));
            str = br.readLine() + br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (!isMessyCode(str)) {
            return encode;
        }

        encode = "ISO-8859-1";
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(multipartFile.getInputStream(), encode));
            str = br.readLine() + br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (!isMessyCode(str)) {
            return encode;
        }
        return "";
    }


    private static boolean isMessyCode(String strName) {
        try {
//			if(strName.length() >= 30){
//				strName = strName.substring(0, 30);
//			}

            Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
            Matcher m = p.matcher(strName);
            String after = m.replaceAll("");
            String temp = after.replaceAll("\\p{P}", "");
            temp = temp.replaceAll("[\\u00A0]+", "");
            temp = temp.replaceAll("\uFEFF", "");
            String regEx = "[\n`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*()——+|{}【】‘；：”“’。， 、？]";
            temp = temp.replaceAll(regEx, "");
            char[] ch = temp.trim().toCharArray();

//			int length = (ch != null) ? ch.length : 0;
//			if(length >= 30){
//				length = 30;
//			}
            int length = ch.length;
            for (int i = 0; i < length; i++) {
                char c = ch[i];
                if (!Character.isLetterOrDigit(c)) {
                    String str = "" + ch[i];
                    if (!str.matches("[\u4e00-\u9fa5]+")) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}
